#include <cstddef>
#include <string.h>
#include <iostream>
using std::cout;
using std::endl;
using std::ostream;
class cowString{
public:
    cowString();
    cowString(const char* str);
    cowString(const cowString & rhs);
    cowString& operator=(const cowString & rhs); 
    ~cowString();

    int refcount();
    int size();
    friend class charProxy;
private:
    //嵌套类
    class charProxy{
    public:
        charProxy(cowString & cowstr, size_t index);
        friend ostream & operator<<(ostream & os,cowString::charProxy charP);
        char& operator=(char ch);
    private:
        cowString& _cowstr;
        int _index;
    };

public:
    charProxy operator[](size_t index);
    friend ostream & operator<<(ostream & os,cowString::charProxy charP);
private:
    char * _pstr;
};

ostream & operator<<(ostream & os,cowString::charProxy charP){
    if(charP._index >= charP._cowstr.size()){
        char nullchar = nullchar;
        cout<<nullchar;
    }else{
        cout << charP._cowstr._pstr[charP._index];
    }
    return os;
}
char& cowString::charProxy::operator=(char ch){
    if(ch != _cowstr._pstr[_index]){ //要赋的值原值不同
        if(_cowstr.refcount() > 1){
            --*(int*)(_cowstr._pstr - 4);
            char* temp = new char[_cowstr.size() + 1 + 4]() + 4;
            *(int *)(temp - 4) = 1;
            strcpy(temp,_cowstr._pstr);
            _cowstr._pstr = temp;
        }
        _cowstr._pstr[_index] = ch;
    }
    return _cowstr._pstr[_index];
}

void test(){
    cowString s("hello");
    cowString s2(s);
    cowString s3(s);
    cout << s[1] << endl;
    s[0] = 'H';
    cout << s[0] << endl;
    cout << s.refcount() <<endl;
    cout << s2.refcount() << endl;
}

int main()
{
    test ();
    return 0;
}



//构造
cowString::cowString()
:_pstr(new char[4+1]()+4){
}

cowString::cowString(const char* str)
:_pstr(new char[strlen(str)+1+4]()+4){
    *(int*)(_pstr-4) = 1;
    strcpy(_pstr,str);
}
cowString::cowString(const cowString & rhs)
:_pstr(rhs._pstr){
    *(int *)(_pstr - 4) += 1;
}
cowString& cowString::operator=(const cowString & rhs)
{
    if(this != &rhs){ //非自赋值
        if(--*(int*)(_pstr-4) == 0){
            delete [] (_pstr-4);
            _pstr = nullptr;
        }
        _pstr = rhs._pstr;
        ++*(int*)(_pstr - 4);
    }
    return *this;
} 
cowString::~cowString(){
    if(--*(int*)(_pstr-4) == 0){
        delete [] (_pstr - 4);
        _pstr = nullptr;
    }
}
//计数
int cowString::refcount(){
        return *(int*)(_pstr-4);
}
//长度
int cowString::size(){
        return strlen(_pstr);
}

//cowstring的构造函数
cowString::charProxy::charProxy(cowString & cowstr, size_t index)
:_cowstr(cowstr)
,_index(index)
{
}
//cowString的运算符=的重载
cowString::charProxy cowString::operator[](size_t index){
        return charProxy(*this,index);
}
